/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.auth.server.handler;

import com.iwindplus.base.domain.vo.ResultVO;
import com.iwindplus.base.util.CryptoUtil;
import com.iwindplus.base.util.ExceptionUtil;
import com.iwindplus.base.util.HttpsUtil;
import com.iwindplus.base.util.JacksonUtil;
import com.iwindplus.base.web.domain.property.GlobalErrorProperty;
import com.iwindplus.base.web.domain.property.ResponseBodyProperty;
import com.iwindplus.base.web.domain.property.ResponseBodyProperty.ResponseBodyCryptoConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

/**
 * 禁止访问处理.
 *
 * @author zengdegui
 * @since 2024/05/22 22:20
 */
@Slf4j
public record UnAccessDeniedHandler(GlobalErrorProperty globalErrorProperty, ResponseBodyProperty responseBodyProperty) implements
    AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
        throws IOException, ServletException {

        UnAccessDeniedHandler.responseData(response, this.globalErrorProperty, this.responseBodyProperty, ResultVO.error(HttpStatus.FORBIDDEN));
    }

    /**
     * 响应数据.
     *
     * @param response             响应
     * @param globalErrorProperty  全局异常配置
     * @param responseBodyProperty 全局响应配置
     * @param result               响应实体
     */
    public static void responseData(HttpServletResponse response, GlobalErrorProperty globalErrorProperty,
        ResponseBodyProperty responseBodyProperty, ResultVO<Object> result) {
        HttpStatusCode httpStatusCode = ExceptionUtil.getHttpStatusCode(globalErrorProperty.getEnabledStatusOk(), result.getBizStatus());

        final ResponseBodyCryptoConfig crypto = responseBodyProperty.getCrypto();
        if (Boolean.TRUE.equals(crypto.getEnabled())) {
            final String encrypt = CryptoUtil.encrypt(JacksonUtil.toJsonStr(result.getBizData()), crypto);
            result.setBizData(encrypt);
        }

        HttpsUtil.responseData(response, httpStatusCode, result);
    }
}